import { World } from './World';
import {
  BackSide,
  DirectionalLight,
  HemisphereLight,
  MathUtils,
  Mesh,
  ShaderMaterial,
  SphereGeometry,
  UniformsUtils,
  Vector3,
} from 'three';
import { SkyShader } from '../lib/SkyShader';

export class Sky extends Mesh {
  protected world: World;
  constructor(world: World) {
    const shader = SkyShader;

    const material = new ShaderMaterial({
      name: 'SkyShader',
      fragmentShader: shader.fragmentShader,
      vertexShader: shader.vertexShader,
      uniforms: UniformsUtils.clone(shader.uniforms),
      side: BackSide,
      depthWrite: false,
    });
    super(new SphereGeometry(1), material);
    const hemiLight: HemisphereLight = new HemisphereLight(0xffffff, 0x080820, 2);
    const directionalLight: DirectionalLight = new DirectionalLight(0xffffff, 0.3);

    const $this: Mesh = this;
    const sun: Vector3 = new Vector3(20, 0, 0);
    const $material = $this.material as ShaderMaterial;
    const uniforms = $material.uniforms;
    enum effectController {
      turbidity = 0.6,
      rayleigh = 0.362,
      mieCoefficient = 0.005,
      mieDirectionalG = 0.7,
      elevation = 45, //维度
      azimuth = 180, //经度
      exposure = 0.5,
    }

    uniforms['rayleigh'].value = effectController.rayleigh;
    uniforms['turbidity'].value = effectController.turbidity;
    uniforms['mieCoefficient'].value = effectController.mieCoefficient;
    uniforms['mieDirectionalG'].value = effectController.mieDirectionalG;

    const phi = MathUtils.degToRad(90 - effectController.elevation);
    const theta = MathUtils.degToRad(effectController.azimuth);

    sun.setFromSphericalCoords(1, phi, theta);
    uniforms['sunPosition'].value.copy(sun);
    world.renderer.toneMappingExposure = effectController.exposure;

    this.scale.setScalar(500);
    world.add(hemiLight);
    world.add(directionalLight);
    world.add(this);
  }
}
